package com.rose.springbootgeneratefile.config;

import com.rose.springbootgeneratefile.api.ConnectionFactory;
import com.rose.springbootgeneratefile.internal.ObjectFactory;
import com.rose.springbootgeneratefile.utils.StringUtility;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCConnectionFactory implements ConnectionFactory {
    private String userId;
    private String password;
    private String connectionURL;
    private String driverClass;
    private Properties otherProperties;


    public JDBCConnectionFactory(JDBCConnectionConfiguration config) {
        super();
        userId = config.getUserId();
        password = config.getPassword();
        connectionURL = config.getConnectionURL();
        driverClass = config.getDriverClass();
        otherProperties = config.getProperties();
    }


    public JDBCConnectionFactory() {
        super();
    }

    public Connection getConnection()
            throws SQLException {
        Driver driver = getDriver();

        Properties props = new Properties();

        if (StringUtility.stringHasValue(userId)) {
            props.setProperty("user", userId); //$NON-NLS-1$
        }

        if (StringUtility.stringHasValue(password)) {
            props.setProperty("password", password); //$NON-NLS-1$
        }

        props.putAll(otherProperties);

        Connection conn = driver.connect(connectionURL, props);

        if (conn == null) {
            throw new SQLException("获取连接失败"); //$NON-NLS-1$
        }

        return conn;
    }

    private Driver getDriver() {
        Driver driver;

        try {
            Class<?> clazz = ObjectFactory.internalClassForName(driverClass);
            driver = (Driver) clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("加载驱动失败"); //$NON-NLS-1$
        }

        return driver;
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        // this should only be called when this connection factory is
        // specified in a ConnectionFactory configuration
        userId = properties.getProperty("userId");
        password = properties.getProperty("password");
        connectionURL = properties.getProperty("connectionURL");
        driverClass = properties.getProperty("driverClass");

        otherProperties = new Properties();
        otherProperties.putAll(properties);

        // remove all the properties that we have specific attributes for
        otherProperties.remove("userId");
        otherProperties.remove("password");
        otherProperties.remove("connectionURL");
        otherProperties.remove("driverClass");
    }
}
